#define NOMINMAX
#include "Engine.h"
#include "NxPhysics.h"
#include "NxControllerManager.h"
#include "NxCapsuleController.h"
#include "PhysicsScene.h"
#include "Basic/Stream.h"
#include "PhysXWrappers.h"
namespace FinalRendering
{
	namespace Engine
	{
		namespace Physics
		{
			PhysScene::PhysScene(Engine * engine)
			{
				phys = engine->GetPhysics();
				NxSceneDesc sceneDesc;
				sceneDesc.gravity.set(0,-640.0f,0);
				scene = phys->createScene(sceneDesc);
				if (!scene)
					throw PhysSceneInitializationException();
				Controller = new PlayerController(engine, scene, vec3(0.0f,54.0f,0.0f));

				NxMaterial * defaultMaterial = scene->getMaterialFromIndex(0); 
				defaultMaterial->setRestitution(0.0f);
				defaultMaterial->setStaticFriction(0.5f);
				defaultMaterial->setDynamicFriction(0.5f);

			}

			PhysScene::~PhysScene()
			{
				
			}

			void PhysScene::Step(float dTime)
			{
				scene->simulate(dTime);
				scene->flushStream();
			}

			void PhysScene::FetchResult()
			{
				scene->fetchResults(NX_RIGID_BODY_FINISHED, true);
			}

			void PhysScene::GetCameraPos(vec3 & pos)
			{
				pos = Controller->GetPosition();
			}

			void PhysScene::Load(const String &fileName)
			{
				FileStream fs(fileName, gxfmRead);
				StreamWrapper s(&fs);
				PhysSceneHeader h;
				fs.ReadBuffer(&h,1);
				for (int i=0; i<h.StaticBrushCount; i++)
				{
					NxConvexShapeDesc convexShapeDesc;
					convexShapeDesc.meshData = phys->createConvexMesh(s);
					if(convexShapeDesc.meshData)
					{            
						NxActorDesc ActorDesc;
						ActorDesc.shapes.pushBack(&convexShapeDesc);
						scene->createActor(ActorDesc);
					}
				}
			}
		}
	}
}